Consolidate construct + constructd into one binary#396
Merged
Conversation
The daemon and client now ship as a single executable. `construct` runs the TUI by default and the daemon under `construct daemon run`; the standalone `constructd` binary stays as a thin back-compat alias. - Promote the daemon's runtime to a library (`crates/daemon/src/lib.rs`) exposing `run`, `init_tracing`, `print_paths`, `DEFAULT_CONFIG_TOML`. `constructd`'s `main.rs` becomes a thin shim over it. - Add a `daemon` subcommand to `construct` (`crates/cli`) that dispatches to the shared lib. Daemon mode is handled before client tracing init and socket discovery so the daemon's verbose log filter applies and it owns the socket rather than connecting to it. - Self-restart replays argv verbatim, so `construct daemon run` re-execs `construct daemon run` and `constructd run` re-execs `constructd run`. This is why a symlink/argv[0] multiplex was rejected (it would drop the name on restart). Verified: restart re-execs the `construct` binary, preserves PID, rebinds the socket, ping works. - Update README, architecture docs, and install.sh to lead with `construct daemon run`; add spec 0026. This consolidates the executable, not the process: the daemon stays a separate long-lived process; running `construct` does not embed a daemon, and running it multiple times yields multiple clients against one daemon.
This was referenced Jun 8, 2026
edwin-zvs
added a commit
that referenced
this pull request
Jun 8, 2026
The daemon has had no unique role since #396/#398: `construct daemon run` runs it and the TUI auto-starts one. `constructd` was just a thin alias, so drop it — the daemon crate (`agentd`) is now library-only and the daemon ships solely inside `construct`. - crates/daemon: remove the `[[bin]] constructd` target and delete the `main.rs` shim; the crate is lib-only now. - e2e harness: spawn `construct daemon run` (and copy `construct` as the relocatable daemon binary) instead of `constructd run`. - scripts/test_agentd.sh, scripts/smoke.sh: launch via `construct daemon run`. - release.yml + install.sh: drop `constructd` from BINS (and `-p agentd` from the release build). The release tarball KEEPS its historical `constructd-<target>` asset name — already-released install.sh / `construct upgrade` builds fetch that exact name, so renaming it would break the download URL. - Docs/spec/comments updated; spec 0026 records that there is no standalone daemon binary and notes the one-time upgrade caveat below. Upgrade caveat (one-time): an `install.sh` baked into an *older* binary lists `constructd` in its `BINS` and aborts when it's absent from the new tarball, so `construct upgrade` across this single version hop fails — re-run the install one-liner instead. New installs and subsequent upgrades are unaffected. Verified: `cargo build --workspace` produces no `constructd`; `cargo test -p agentd` (66) and the e2e restart suite (3, incl. `restart_reloads_updated_binary`) pass with the daemon spawned as `construct daemon run`.
Merged
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Consolidates the daemon (
constructd) and the TUI/CLI client (construct) into a single executable.constructruns the TUI by default and the daemon underconstruct daemon run. The standaloneconstructdbinary stays as a thin back-compat alias —constructd runandconstruct daemon runare equivalent and share 100% of their code path.This consolidates the executable, not the process: the daemon is still a separate long-lived process that many clients attach to. Running
constructdoes not embed/auto-spawn a daemon, and running it multiple times yields multiple clients against one daemon — never multiple daemons.How
crates/daemon/src/lib.rs), exposingrun,init_tracing,print_paths,DEFAULT_CONFIG_TOML.constructd'smain.rsbecomes a ~45-line shim over it (−466 lines).constructgains adaemonsubcommand (crates/clinow depends on theagentdlib). Daemon mode is dispatched before client tracing init and socket discovery, so the daemon's verbose log filter applies and it owns the socket rather than connecting to it.session::request_daemon_restartre-execs by replayingstd::env::args().skip(1)verbatim, soconstruct daemon run …re-execsconstruct daemon run …andconstructd runre-execsconstructd run. A symlink /argv[0]-multiplex approach was rejected because resolving aconstructd→constructsymlink would drop the name while the replayed args still assume daemon dispatch — breaking upgrade-restart.construct daemon run; design recorded inspecs/0026-single-binary-daemon-and-client.md.Verification
cargo build(full workspace) ✓ ·cargo test -p agentd→ 66 passed ✓construct daemon default-configis byte-identical toconstructd default-config✓construct daemon run,construct ping→ pong,construct listshows the orchestrator ✓; same viaconstructd run✓exec(): triggereddaemon.restartover IPC against a daemon started withconstruct daemon run→ re-execs theconstructbinary, PID preserved, socket rebinds,construct pingworks after, twolisteninglog lines ✓Notes
constructbinary now links both dependency sets (TUI + daemon server/tunnel); most heavy deps are already shared. We ship one file instead of two.construct-mcpare intentionally not merged — they're a separate process/plugin boundary.constructdis still built and shipped, so existing installs/scripts and the atomic-rename upgrade layout keep working. Dropping it entirely (and frominstall.sh'sBINS) is a trivial, separate follow-up if desired.🤖 Generated with Claude Code